/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ipti.br.tag.bean;

import org.ipti.br.tag.bo.AddInfoPersonageBO;
import org.ipti.br.tag.bo.AdditionalInfoBO;
import org.ipti.br.tag.bo.AdditionalInfoTypeBO;
import org.ipti.br.tag.bo.AddressBO;
import org.ipti.br.tag.bo.EthnicityBO;
import org.ipti.br.tag.bo.HumanBO;
import org.ipti.br.tag.bo.LoginBO;
import org.ipti.br.tag.bo.NationalityBO;
import org.ipti.br.tag.bo.NeighborhoodBO;
import org.ipti.br.tag.bo.StreetBO;
import org.ipti.br.tag.bo.ZipcodeBO;
import org.ipti.br.tag.entity.AdditionalInfo;
import org.ipti.br.tag.entity.AdditionalInfoType;
import org.ipti.br.tag.entity.Address;
import org.ipti.br.tag.entity.Ethnicity;
import org.ipti.br.tag.entity.Human;
import org.ipti.br.tag.entity.Login;
import org.ipti.br.tag.entity.enums.Laterality;
import org.ipti.br.tag.entity.enums.MaritalStatus;
import org.ipti.br.tag.entity.Nationality;
import org.ipti.br.tag.entity.Neighborhood;
import org.ipti.br.tag.entity.Street;
import org.ipti.br.tag.entity.Zipcode;
import org.ipti.br.tag.entity.enums.Sex;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
import javax.faces.model.SelectItem;
import org.ipti.br.tag.bean.lazy.LazyHumanDataModel;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import org.ipti.br.tag.util.LoginUtil;

/**
 *
 * @author root
 */
@Named(value="humanEdit")
@SessionScoped
public class HumanEditBean extends AppBaseBean {

    @Inject
    private AdditionalInfoBO additionalInfoBO;
    @Inject
    private AdditionalInfoTypeBO additionalInfoTypeBO;
    @Inject
    private AddInfoPersonageBO addInfoPersonageBO;
    @Inject
    private AddressBO addressBO;
    @Inject
    private EthnicityBO ethnicityBO;
    @Inject
    private HumanBO humanBO;
    @Inject
    private NationalityBO nationalityBO;
    @Inject
    private ZipcodeBO zipcodeBO;
    @Inject
    private NeighborhoodBO neighborhoodBO;
    @Inject
    private StreetBO streetBO;
    @Inject
    private LoginBO loginBO;
    private Address address;
    private Human human;
    private Zipcode zipcode;
    private Long ethnicityID;
    private Long humanID;
    private Long nationalityID;
    private String street;
    private String cep;
    private String neighborhood;
    private boolean showAddress;
    private List<AdditionalInfo> additionalInfoList;
    private List<SelectItem> maritalStatusList;
    private List<SelectItem> nationalityList;
    private List<SelectItem> lateralityList;
    private List<SelectItem> sexList;
    private List<SelectItem> ethnicityList;
//============================================
    private Human humanRegister;
    private String mask;
    private Address addressRegister;
    private Zipcode zipcodeRegister;
    private String cepRegister;
    private String neighborhoodRegister;
    private String streetRegister;
    private String additionalInfoRegister;
    private Long ethnicityIDRegister;
    private Long nationalityIDRegister;
    private Long addInfoTypeIDRegister;
    private boolean showAddressRegister;
    private List<SelectItem> additionalInfoTypeListRegister;
    private List<SelectItem> sexListRegister;
    private LazyHumanDataModel humanList;
    private Human genericHuman;
    public HumanEditBean() {
    }

     //==========================================================================
    public void prepareNewMale() {
        initializeHuman();
        sexListRegister = new ArrayList<SelectItem>();
        sexListRegister.add(new SelectItem(Sex.MALE, "Masculino"));
    }

    public void prepareNewFemale() {
        initializeHuman();
        sexListRegister = new ArrayList<SelectItem>();
        sexListRegister.add(new SelectItem(Sex.FEMALE, "Feminino"));
    }

    public void prepareNewHuman() {
        initializeHuman();
        sexListRegister = new ArrayList<SelectItem>();
        sexListRegister.add(new SelectItem(Sex.MALE, "Feminino"));
        sexListRegister.add(new SelectItem(Sex.MALE, "Masculino"));
    }

    public boolean validateZipcodeRegister() {
        if (zipcodeRegister != null) {
            return true;
        } else {
            return false;
        }
    }
    
    public void createNewHuman() {
        try {
            if (validateZipcodeRegister()) {
                Ethnicity ethnicity = new Ethnicity();
                ethnicity.setId(ethnicityIDRegister);
                humanRegister.setEthnicity(ethnicity);
                Nationality nationality = new Nationality();
                nationality.setId(nationalityIDRegister);
                humanRegister.setNationality(nationality);

                addressRegister.setZipcode(zipcodeRegister);
                Neighborhood neighborhoodAux = neighborhoodBO.searchByNameCity(neighborhoodRegister, zipcodeRegister.getCity().getId());
                Street streetAux = streetBO.searchByNameCity(streetRegister, zipcodeRegister.getCity().getId());

                if (neighborhoodAux == null) {
                    neighborhoodAux = new Neighborhood(neighborhoodRegister, zipcodeRegister.getCity());
                    neighborhoodBO.create(neighborhoodAux);
                }
                if (streetAux == null) {
                    streetAux = new Street(streetRegister, zipcodeRegister.getCity());
                    streetBO.create(streetAux);
                }

                addressRegister.setNeighborhood(neighborhoodAux);
                addressRegister.setStreet(streetAux);

                Long addressID = addressBO.searchExactAddress(addressRegister);

                if (addressID == null || addressID.equals(0L)) {
                    addressBO.create(addressRegister);
                } else {
                    addressRegister.setId(addressID);
                }

                humanRegister.setAddress(addressRegister);
                humanBO.getHumanDAO().syncCreate(humanRegister);//humanBO.create(humanRegister);

                if (addInfoTypeIDRegister != 0L) {
                    AdditionalInfoType ait = new AdditionalInfoType();
                    ait.setId(addInfoTypeIDRegister);

                    AdditionalInfo ai = new AdditionalInfo();
                    ai.setValue(additionalInfoRegister);
                    ai.setPerson(humanRegister);
                    ai.setAdditionalInfoType(ait);
                    additionalInfoBO.create(ai);
                }                

                if (sexListRegister.size() < 2) {
                    if (humanRegister.getSex() == Sex.MALE) {
                        //System.out.println("Cadastrando pai");
                        human.setFather(humanRegister);
                    } else {
                        //System.out.println("Cadastrando mãe");
                        human.setMother(humanRegister);
                    }
                } else {
                    //System.out.println("Cadastrando sponsor");
                    human.setSponsor(humanRegister);
                }
                //getHumanBO().edit(human);
                initializeHuman();
            }
        } catch (Exception ex) {
        }
    }

    public void initializeHuman() {
        addressRegister = new Address();
        humanRegister = new Human();
        humanRegister.setBirthday(Calendar.getInstance());
        neighborhoodRegister = "";
        streetRegister = "";
        cepRegister = "";
        zipcodeRegister = null;

        showAddressRegister = false;

        loadAddInfoTypeList();
    }

    public void searchCEPRegister() {
        neighborhoodRegister = "";
        streetRegister = "";
        zipcodeRegister = zipcodeBO.searchByCode(Integer.parseInt(cepRegister));
        if (zipcodeRegister == null) {
            showAddressRegister = false;
            addInfoMessage("addHumanForm:addHumanView", "CEP não cadastrado.", null);
        } else {
            if (zipcodeRegister.getNeighborhood() != null) {
                neighborhoodRegister = zipcodeRegister.getNeighborhood().getName();
            }
            if (zipcodeRegister.getStreet() != null) {
                streetRegister = zipcodeRegister.getStreet().getName();
            }
            showAddressRegister = true;
        }
    }

    public List<String> neighborhoodCompleteRegister(String query) {
        return neighborhoodBO.neighborhoodList(query, zipcodeRegister.getCity());
    }

    public List<String> streetCompleteRegister(String query) {
        return streetBO.streetList(query, zipcodeRegister.getCity());
    }

    public void loadAddInfoTypeList() {
        additionalInfoTypeListRegister = new ArrayList<SelectItem>();
        additionalInfoTypeListRegister.add(new SelectItem(0L, "Selecione um tipo"));
        for (AdditionalInfoType ait : addInfoPersonageBO.findAddInfoTypeWithPersonage()) {
            additionalInfoTypeListRegister.add(new SelectItem(ait.getId(), ait.getAcronym()));
        }
    }

    public void loadMask(Long aditID) {
        if (aditID == 0) {
            mask = null;
        } else {
            mask = additionalInfoTypeBO.find(aditID).getMask();
        }
    }
    
    public void prepareFatherSearch() {
        humanList = new LazyHumanDataModel(humanBO.getHumanDAO(), Sex.MALE);
        genericHuman = null;
    }

    public void prepareMotherSearch() {
        humanList = new LazyHumanDataModel(humanBO.getHumanDAO(), Sex.FEMALE);
        genericHuman = null;
    }

    public void prepareSponsorSearch() {
        humanList = new LazyHumanDataModel(humanBO.getHumanDAO(), null);
        genericHuman = null;
    }

    public void configureFatherMotherSponsor() {
        if (genericHuman != null) {
            if (humanList.getSex() == null) {
                human.setSponsor(genericHuman);
            } else if (humanList.getSex() == Sex.MALE) {
                human.setFather(genericHuman);
            } else {
                human.setMother(genericHuman);
            }
            genericHuman = null;
            getHumanBO().edit(human);
        }
    }
    //==========================================================================
    
    public void searchCEP() {
        neighborhood = "";
        street = "";
        zipcode = zipcodeBO.searchByCode(Integer.parseInt(cep));
        if (zipcode == null) {
            showAddress = false;
            addInfoMessage("humanEditForm:humanTabView:cep", "CEP não cadastrado.", null);
        } else {
            if (zipcode.getNeighborhood() != null) {
                neighborhood = zipcode.getNeighborhood().getName();
            }
            if (zipcode.getStreet() != null) {
                street = zipcode.getStreet().getName();
            }
            showAddress = true;
        }
    }

    public List<String> neighborhoodComplete(String query) {
        return neighborhoodBO.neighborhoodList(query, zipcode.getCity());
    }

    public List<String> streetComplete(String query) {
        return streetBO.streetList(query, zipcode.getCity());
    }

    public void initialize() {

        human = getHumanBO().find(humanID);
        address = human.getAddress();
        zipcode = address.getZipcode();
        cep = String.valueOf(address.getZipcode().getCode());
        neighborhood = address.getNeighborhood().getName();
        street = address.getStreet().getName();

        String number = address.getNumber();
        String complement = address.getComplement();
        address = new Address();
        address.setNumber(number);
        address.setComplement(complement);
        showAddress = true;

        ethnicityID = human.getEthnicity().getId();
        nationalityID = human.getNationality().getId();

        loadAddInfoList();
        loadLateralityList();
        loadMaritalStatusList();
        loadNationalityList();
        loadSexList();
        loadEthnicityList();
    }

    public String getUsername() {
        Login login = loginBO.find(humanID);
        if (login != null) {
            return login.getUserName();
        } else {
            return "";
        }
    }

    public void edit() {
        try {
            if (validateZipcode()) {
                for (AdditionalInfo ai : additionalInfoList) {
                    getAdditionalInfoBO().edit(ai);
                }

                address.setZipcode(zipcode);
                Neighborhood neighborhoodAux = neighborhoodBO.searchByNameCity(neighborhood, zipcode.getCity().getId());
                Street streetAux = streetBO.searchByNameCity(street, zipcode.getCity().getId());

                if (neighborhoodAux == null) {
                    neighborhoodAux = new Neighborhood(neighborhood, zipcode.getCity());
                    neighborhoodBO.create(neighborhoodAux);
                }
                if (streetAux == null) {
                    streetAux = new Street(street, zipcode.getCity());
                    streetBO.create(streetAux);
                }

                address.setNeighborhood(neighborhoodAux);
                address.setStreet(streetAux);

                Long addressID = addressBO.searchExactAddress(address);

                if (addressID == null || addressID.equals(0L)) {
                    addressBO.create(address);
                } else {
                    address.setId(addressID);
                }

                human.setAddress(address);

                Ethnicity ethnicity = new Ethnicity();
                ethnicity.setId(ethnicityID);
                human.setEthnicity(ethnicity);
                Nationality nationality = new Nationality();
                nationality.setId(nationalityID);
                human.setNationality(nationality);
                getHumanBO().edit(human);

                String userName = "";
                int precedence = Integer.MAX_VALUE;
                for (AdditionalInfo addInfo : additionalInfoList) {
                    if (addInfo.getAdditionalInfoType().getPrecedence() < precedence) {
                        userName = addInfo.getValue();
                        precedence = addInfo.getAdditionalInfoType().getPrecedence();
                    }
                }

                Login login = loginBO.findLoginPerPerson(humanID);
                login.setUserName(LoginUtil.selectNumbersLetters(userName));
                if (login.getUserName().isEmpty()) {
                    login.setUserName(null);
                }
                loginBO.edit(login);
                initialize();
                addInfoMessage(":humanEditForm:msg", "Edição realizada com sucesso.", null);
            }
        } catch (Exception ex) {
            addErrorMessage(":humanEditForm:msg", "Um erro inesperado foi encontrado", null);
        }
    }

    public boolean validateZipcode() {
        if (zipcode != null) {
            return true;
        } else {
            addErrorMessage("humanEditForm", "'Endereço' é obrigatório", null);
            return false;
        }
    }

    public List<AdditionalInfo> personAdditionalInfo(Long personID) {
        return getAdditionalInfoBO().findAddInfosPerPerson(personID);
    }

    public void loadAddInfoList() {
        additionalInfoList = new ArrayList<AdditionalInfo>();
        for (AdditionalInfo ai : getAdditionalInfoBO().findAddInfosPerPerson(human.getId())) {
            additionalInfoList.add(ai);
        }
    }

    public void loadLateralityList() {
        lateralityList = new ArrayList<SelectItem>();
        lateralityList.add(new SelectItem(Laterality.Ambidextrous, "Ambidestro"));
        lateralityList.add(new SelectItem(Laterality.LeftHanded, "Canhoto"));
        lateralityList.add(new SelectItem(Laterality.RightHanded, "Destro"));
    }

    public void loadMaritalStatusList() {
        maritalStatusList = new ArrayList<SelectItem>();
        maritalStatusList.add(new SelectItem(MaritalStatus.Married, "Casado"));
        maritalStatusList.add(new SelectItem(MaritalStatus.Divorced, "Divorciado"));
        maritalStatusList.add(new SelectItem(MaritalStatus.Single, "Solteiro"));
        maritalStatusList.add(new SelectItem(MaritalStatus.Widowed, "Viúvo"));
    }

    public void loadNationalityList() {
        nationalityList = new ArrayList<SelectItem>();
        for (Nationality n : getNationalityBO().findAllOrder()) {
            nationalityList.add(new SelectItem(n.getId(), n.getPatronym()));
        }
    }

    public void loadEthnicityList() {
        ethnicityList = new ArrayList<SelectItem>();
        for (Ethnicity e : getEthnicityBO().findAllOrder()) {
            ethnicityList.add(new SelectItem(e.getId(), e.getName()));
        }
    }

    public void loadSexList() {
        sexList = new ArrayList<SelectItem>();
        sexList.add(new SelectItem(Sex.FEMALE, "Feminino"));
        sexList.add(new SelectItem(Sex.MALE, "Masculino"));
    }

    public AdditionalInfoBO getAdditionalInfoBO() {
        return additionalInfoBO;
    }

    public void setAdditionalInfoBO(AdditionalInfoBO additionalInfoBO) {
        this.additionalInfoBO = additionalInfoBO;
    }

    public AdditionalInfoTypeBO getAdditionalInfoTypeBO() {
        return additionalInfoTypeBO;
    }

    public void setAdditionalInfoTypeBO(AdditionalInfoTypeBO additionalInfoTypeBO) {
        this.additionalInfoTypeBO = additionalInfoTypeBO;
    }

    public AddInfoPersonageBO getAddInfoPersonageBO() {
        return addInfoPersonageBO;
    }

    public void setAddInfoPersonageBO(AddInfoPersonageBO addInfoPersonageBO) {
        this.addInfoPersonageBO = addInfoPersonageBO;
    }

    public AddressBO getAddressBO() {
        return addressBO;
    }

    public void setAddressBO(AddressBO addressBO) {
        this.addressBO = addressBO;
    }

    public EthnicityBO getEthnicityBO() {
        return ethnicityBO;
    }

    public void setEthnicityBO(EthnicityBO ethnicityBO) {
        this.ethnicityBO = ethnicityBO;
    }

    public HumanBO getHumanBO() {
        return humanBO;
    }

    public void setHumanBO(HumanBO humanBO) {
        this.humanBO = humanBO;
    }

    public NationalityBO getNationalityBO() {
        return nationalityBO;
    }

    public void setNationalityBO(NationalityBO nationalityBO) {
        this.nationalityBO = nationalityBO;
    }

    public List<AdditionalInfo> getAdditionalInfoList() {
        return additionalInfoList;
    }

    public void setAdditionalInfoList(List<AdditionalInfo> additionalInfoList) {
        this.additionalInfoList = additionalInfoList;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public Long getEthnicityID() {
        return ethnicityID;
    }

    public void setEthnicityID(Long ethnicityID) {
        this.ethnicityID = ethnicityID;
    }

    public Human getHuman() {
        return human;
    }

    public void setHuman(Human human) {
        this.human = human;
    }

    public Long getHumanID() {
        return humanID;
    }

    public void setHumanID(Long humanID) {
        this.humanID = humanID;
    }

    public List<SelectItem> getLateralityList() {
        return lateralityList;
    }

    public void setLateralityList(List<SelectItem> lateralityList) {
        this.lateralityList = lateralityList;
    }

    public List<SelectItem> getMaritalStatusList() {
        return maritalStatusList;
    }

    public void setMaritalStatusList(List<SelectItem> maritalStatusList) {
        this.maritalStatusList = maritalStatusList;
    }

    public Long getNationalityID() {
        return nationalityID;
    }

    public void setNationalityID(Long nationalityID) {
        this.nationalityID = nationalityID;
    }

    public List<SelectItem> getNationalityList() {
        return nationalityList;
    }

    public void setNationalityList(List<SelectItem> nationalityList) {
        this.nationalityList = nationalityList;
    }

    public String getNeighborhood() {
        return neighborhood;
    }

    public void setNeighborhood(String neighborhood) {
        this.neighborhood = neighborhood;
    }

    public NeighborhoodBO getNeighborhoodBO() {
        return neighborhoodBO;
    }

    public void setNeighborhoodBO(NeighborhoodBO neighborhoodBO) {
        this.neighborhoodBO = neighborhoodBO;
    }

    public List<SelectItem> getSexList() {
        return sexList;
    }

    public void setSexList(List<SelectItem> sexList) {
        this.sexList = sexList;
    }

    public boolean isShowAddress() {
        return showAddress;
    }

    public void setShowAddress(boolean showAddress) {
        this.showAddress = showAddress;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public StreetBO getStreetBO() {
        return streetBO;
    }

    public void setStreetBO(StreetBO streetBO) {
        this.streetBO = streetBO;
    }

    public Zipcode getZipcode() {
        return zipcode;
    }

    public void setZipcode(Zipcode zipcode) {
        this.zipcode = zipcode;
    }

    public ZipcodeBO getZipcodeBO() {
        return zipcodeBO;
    }

    public void setZipcodeBO(ZipcodeBO zipcodeBO) {
        this.zipcodeBO = zipcodeBO;
    }

    public List<SelectItem> getEthnicityList() {
        return ethnicityList;
    }

    public void setEthnicityList(List<SelectItem> ethnicityList) {
        this.ethnicityList = ethnicityList;
    }

    public Long getAddInfoTypeIDRegister() {
        return addInfoTypeIDRegister;
    }

    public void setAddInfoTypeIDRegister(Long addInfoTypeIDRegister) {
        this.addInfoTypeIDRegister = addInfoTypeIDRegister;
    }

    public String getAdditionalInfoRegister() {
        return additionalInfoRegister;
    }

    public void setAdditionalInfoRegister(String additionalInfoRegister) {
        this.additionalInfoRegister = additionalInfoRegister;
    }

    public List<SelectItem> getAdditionalInfoTypeListRegister() {
        return additionalInfoTypeListRegister;
    }

    public void setAdditionalInfoTypeListRegister(List<SelectItem> additionalInfoTypeListRegister) {
        this.additionalInfoTypeListRegister = additionalInfoTypeListRegister;
    }

    public Address getAddressRegister() {
        return addressRegister;
    }

    public void setAddressRegister(Address addressRegister) {
        this.addressRegister = addressRegister;
    }

    public String getCepRegister() {
        return cepRegister;
    }

    public void setCepRegister(String cepRegister) {
        this.cepRegister = cepRegister;
    }

    public Long getEthnicityIDRegister() {
        return ethnicityIDRegister;
    }

    public void setEthnicityIDRegister(Long ethnicityIDRegister) {
        this.ethnicityIDRegister = ethnicityIDRegister;
    }

    public Human getGenericHuman() {
        return genericHuman;
    }

    public void setGenericHuman(Human genericHuman) {
        this.genericHuman = genericHuman;
    }

    public LazyHumanDataModel getHumanList() {
        return humanList;
    }

    public void setHumanList(LazyHumanDataModel humanList) {
        this.humanList = humanList;
    }

    public Human getHumanRegister() {
        return humanRegister;
    }

    public void setHumanRegister(Human humanRegister) {
        this.humanRegister = humanRegister;
    }

    public String getMask() {
        return mask;
    }

    public void setMask(String mask) {
        this.mask = mask;
    }

    public Long getNationalityIDRegister() {
        return nationalityIDRegister;
    }

    public void setNationalityIDRegister(Long nationalityIDRegister) {
        this.nationalityIDRegister = nationalityIDRegister;
    }

    public String getNeighborhoodRegister() {
        return neighborhoodRegister;
    }

    public void setNeighborhoodRegister(String neighborhoodRegister) {
        this.neighborhoodRegister = neighborhoodRegister;
    }

    public List<SelectItem> getSexListRegister() {
        return sexListRegister;
    }

    public void setSexListRegister(List<SelectItem> sexListRegister) {
        this.sexListRegister = sexListRegister;
    }

    public boolean isShowAddressRegister() {
        return showAddressRegister;
    }

    public void setShowAddressRegister(boolean showAddressRegister) {
        this.showAddressRegister = showAddressRegister;
    }

    public String getStreetRegister() {
        return streetRegister;
    }

    public void setStreetRegister(String streetRegister) {
        this.streetRegister = streetRegister;
    }

    public Zipcode getZipcodeRegister() {
        return zipcodeRegister;
    }

    public void setZipcodeRegister(Zipcode zipcodeRegister) {
        this.zipcodeRegister = zipcodeRegister;
    }
        
}